package yawning.mew.cat;

import yawning.mew.ProcEffect.Trigger;
import yawning.mew.cat.CatModelSimulation.SimulatorProperty;
import yawning.mew.character.CharacterModel.AttackResult;
import yawning.mew.sim.SimulationAction;

public class ShredAction implements SimulationAction {
	private CatModelSimState mState;

	ShredAction(CatModelSimState state) {
		mState = state;
	}

	public double perform() {
		int cost = mState.getEnergyCost(mState.mModel.shredCost);
		if (mState.getEnergy() < cost && !mState.oocEv.isUp()) return SimulationAction.ACTION_FAIL;

		AttackResult result = mState.mModel.getYellowResult();

		if (mState.mDebug) mState.DBGF("Shred (%s)", result);

		if (result == AttackResult.MISS) {
			cost = (int) Math.round(cost * 0.2);
			mState.nrShredMiss++;
		} else if (result == AttackResult.DODGE) {
			cost = (int) Math.round(cost * 0.2);
			mState.nrShredDodge++;
		} else {
			double damage = mState.mModel.getWeaponDamage() * mState.mModel.levelDep.getShredMult() + mState.mModel.levelDep.getShredDmg();

			if (result == AttackResult.CRIT) {
				mState.nrShredCrit++;
				damage *= mState.mModel.multCrit;
				mState.mSimUtil.triggerProc(Trigger.YELLOWCRIT);
			} else {
				mState.nrShredHit++;
				mState.mSimUtil.triggerProc(Trigger.YELLOW);
			}

			damage *= mState.getDirectDamageMult();
			if (mState.mSimUtil.getConfig().getBool(SimulatorProperty.ASSUMEEXTERNALBLEED) || mState.rakeEv.isUp() || mState.ripEv.isUp()) {
				damage *= mState.mModel.multShredRnT;
			}
			damage *= mState.mangleEv.isUp() ? mState.mModel.multMangle : 1;
			mState.shredDamage += Math.round(damage);

			if (mState.mDebug) mState.DBGF("  Damage: %d", Math.round(damage));

			// Handle glyph of shred.
			if (mState.ripEv.isUp() && mState.mModel.shredRipExtDuration > 0) mState.ripEv.onShred();

			mState.onCpGenerator(result == AttackResult.CRIT);
		}

		mState.onOoCConsumer(cost);
		return 1.0;
	}
};